/*
- Malt Project - string.cpp
- This document is protected by the GPL protocol.
- Writer:@Index-Flandre
*/

#include "../../include/object/string.hpp"

namespace malt
{

String NullString;

extern inline void StringInit()
{
	NullString.tp = &StringType;
	NullString.size = 0;
}

Object *NewString()
{
	String *str = new String();
	str->tp = &StringType;
	return str;
}

Object *NewString(char *obj, unsigned long size)
{
	String *str = new String(obj, size);
	str->tp = &StringType;
	return str;
}

Object *NewChar(char ch)
{
	// add char intern
	// ...
	String *str = new String();
	str->tp = &StringType;
	str->chars = new char[1];
	str->chars[0] = ch;
	return str;
}

Object *NewSymbol()
{
	Symbol *sym = new Symbol();
	sym->tp = &SymbolType;
	return sym;
}

Object *NewSymbol(char *obj, unsigned long size)
{
	Symbol *sym = new Symbol();
	sym->tp = &SymbolType;
	sym->chars = obj;
	sym->size = size;
	return sym;
}

char *CopyStr(const char *str, unsigned long size)
{
	char *cs = new char[size];
	for (unsigned long i = 0; i < size; i++)
	{
		cs[i] = str[i];
	}
	return cs;
}

String::String() {}
String::String(char *obj, unsigned long size)
{
	this->size = size;
	chars = obj;
}

bool String::eq(Object *obj)
{
	if (tp != obj->tp)
		return false;
	if (hash_value != ((String *)obj)->hash_value)
		return false;
	else if (size != ((String *)obj)->size)
		return false;
	else
	{
		for (unsigned long i = 0; i < size; i++)
		{
			if (chars[i] != ((String *)obj)->chars[i])
				return false;
		}
		return true;
	}
}
void String::repl_print()
{
	if (chars == NULL || size == 0)
		printf("\e[30;1m\"\"\e[0m");
	else
		printf("\e[30;1m\"%s\"\e[0m", chars);
}
unsigned long String::Hash()
{
	if (hash_value != 0)
		return hash_value;
	unsigned long strsize = size;
	unsigned long seed = 131;
	unsigned long hash = 0;
	for (unsigned long i = 0; i < strsize; i++)
	{
		hash = hash * seed + (chars[i] + 1);
	}
	hash_value = (hash & 0x7fffffff);
	return hash_value;
}
void Symbol::repl_print()
{
	if (!(chars == NULL || size == 0))
		printf("\e[35;1m%s\e[0m", chars);
}
}